/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package edu.utx.spot.timesync;

import com.sun.spot.peripheral.Spot;
import com.sun.spot.peripheral.IAT91_TC;
import com.sun.spot.peripheral.TimerCounterBits;
import com.sun.squawk.VM;

/**
 *
 */
public class AT91TimerCounterSyncClock implements ISyncClock {

    private IAT91_TC testTimer;
    private IAT91_TC clockTimer;
    private AT91TimerCounterThread clockThread;
    
    // TC2 is connected to the CC2420 start of frame delimiter.  Use
    // it as the system clock and timestamp engine.
    private final int TEST_AT91_TC_INDEX = 1;
    private final int CLOCK_AT91_TC_INDEX = 2;
    
    //
    // CLKS_MCK2 (MCK/2)
    //  ticks per ms: 29952
    //  ms per irq: 2
    // CLKS_MCK8 (MCK/8)
    //  ticks per ms: 7448
    //  ms per irq: 8
    // CLKS_MCK32 (MCK/32)
    //  ticks per ms: 1872
    //  ms per irq: 30
    //
    private int usecsPerIrq = 30000;
    private int ticksPerIrq = 1872 * 30;

    
    public AT91TimerCounterSyncClock() {
        this.clockTimer = Spot.getInstance().getAT91_TC(CLOCK_AT91_TC_INDEX);
        this.testTimer = Spot.getInstance().getAT91_TC(TEST_AT91_TC_INDEX);
        this.clockThread = new AT91TimerCounterThread(clockTimer, testTimer, usecsPerIrq, ticksPerIrq);
		
		// get the SFD pin
        clockTimer.claimTIOA();
		
        // configure and start timer thread
        VM.setAsDaemonThread(clockThread);
        VM.setSystemThreadPriority(clockThread, Thread.MAX_PRIORITY);
        clockThread.start();
		
		// configure test timer
        testTimer.configure(
							TimerCounterBits.TC_CAPT |             // capture mode
							TimerCounterBits.TC_CLKS_MCK32 |        // fast clock
							TimerCounterBits.TC_CPCTRG);           // reset counter on compare
        testTimer.setRegC(ticksPerIrq);
		
        // configure clock timer
        clockTimer.configure(
							 TimerCounterBits.TC_CAPT |             // capture mode
							 TimerCounterBits.TC_CLKS_MCK32 |        // fast clock
							 TimerCounterBits.TC_LDRA_RISING_EDGE | // load RA on rising edge
							 TimerCounterBits.TC_CPCTRG);           // reset counter on compare
        clockTimer.setRegC(ticksPerIrq);
		
        // start counters
        testTimer.enableAndReset();
        clockTimer.enableAndReset();
		
        // synchronize clocks
        testTimer.blockSync();
    }
    
    //
    // ISyncClock
    //

    // time
    public long currentTimeMillis() {
        return currentTimeMicros() / 1000;
    }

    public long currentTimeMicros() {
        return clockThread.currentTimeMicros();
    }

    // adjustment
    public void setClockOffset(long offset) {
		clockThread.setClockOffset(offset);
    }
	
    public void setClockRate(long rate) {

    }
    
    public long sfdTimestampTX() {
        return clockThread.lastTimestamp();
    }
    
    public long sfdTimestampRX() {
        return clockThread.lastTimestamp();
    }

	public boolean isSfdHigh() {
		return clockThread.isSfdHigh();
	}
	
	//
	// IDriver
 	//
	public void setUp() {
		System.out.println("setUp - AT91_TC sync clock");
	}
	
	public boolean tearDown() {
		clockTimer.unclaimTIOA();
		clockTimer.disable();
		testTimer.disable();
		return true;
	}
	
	public void shutDown() {
	}
	
    public String getDriverName() {
        return "AT91_TC";
    }
}
